import isObject from "./isObject"
import store from '../src/store';
// 单利模式
class wss {
	// 断开重连的状态
	static duanKaiChongLianFlag = true;
	// 断开重连的次数
	static duanKaiCiShu = 10
	// 断开重连初试定时时间
	static duanKaiTime = 1000
	// webscoket 服务 链接存储值
	static ws = null
	// 心跳检测 
	static xinTiaoFlag = true
	// 离线消息队列
	static XiaoXiList = []

	static num = 1
	static async connectWS() {

		// console.log(wss.ws, 15)
		// console.log("jinlai le ", wss.ws?.readyState)
		// 如果允许断开重连 
		if (wss.duanKaiChongLianFlag) {
			console.log("zoule")
			// 如果断开次数大于0 就一直循环
			while (wss.duanKaiCiShu > 0) {
				// 第一次链接 不需要定时  也就是说 一进入页面 就开始执行 
				await wss.initWs()
				// 等待 duanKaiTime 秒后 在继续执行
				await wss.WAITS(wss.duanKaiTime)
				// 每次重连的时间 在原基础上 扩大2倍
				wss.duanKaiTime *= 2
				// 重连次数 每次减一
				wss.duanKaiCiShu--
			}
		}
	}

	static initWs() {
		return new Promise((resolve) => {


			wss.ws = new WebSocket("ws://127.0.0.1:3003")

			wss.ws.onopen = async () => {
				// 次数改成0 是为了终止循环 
				wss.duanKaiCiShu = 0
				// 断开重连状态改成 false
				wss.duanKaiChongLianFlag = false
				resolve()
				// 将消息队列里面的内容 发送一遍
				for (var $i = 0; $i < wss.XiaoXiList.length; $i++) {
					wss.sendMsg(wss.XiaoXiList[$i])
				}
				// 心跳检测定时器 每3秒执行一次
				let xinTiaoIVL = setInterval(() => {
					// 如果心跳的装填 是true 代表正常 就继续向服务端推送数据
					if (wss.xinTiaoFlag) {
						// 推送数据前  先将状态改为false  当服务端给了回复之后 在将此状态 改为true
						wss.xinTiaoFlag = false
						// 向服务端推送数据
						wss.sendMsg({ type: "heart" })
					} else {
						// 如果走到else 说明链接超时了  
						// 如果链接超时 需要 清空定时器
						clearInterval(xinTiaoIVL)
						// 清空定时器
						// xinTiaoIVL = null
						// 回复重连次数 
						wss.duanKaiCiShu = 10
						// 更改 重连装填 为允许重连
						wss.duanKaiChongLianFlag = true
						// 心跳状态回复为 正常
						wss.xinTiaoFlag = true
						// 调用重连方法 进行重连操作
						wss.connectWS()
					}
				}, 3000)

			}

			wss.ws.onmessage = (evt) => {
				// console.log("收到消息")
				// console.log(evt.data, 13)
				let data
				try {
					// JSON.parse("12345")
					data = JSON.parse(evt.data)

					if (isObject(data)) {
						// console.log(data)
						// 如果type是 心跳检测
						// store.dispatch('heart',data)
						store.dispatch(data.type, data)
						if (data.type === 'heart') {
							// console.log("链接正常")
							// 将心跳状态 回复成正常 【xinTiaoFlag =false 代表服务端没有回复消息 就是异常状态】
							wss.xinTiaoFlag = true

						}
						// 存vuex 

					} else {
						console.log(data, "这是个字符串")
					}

				} catch (e) {
					console.log(data)
					//TODO handle the exception
				}
			}
			wss.ws.onclose = () => {
				// connectWS()
			}
			wss.ws.onerror = (err) => {
				console.log("error")
			}
		});
	}



	static WAITS(times = 1000) {
		return new Promise((resolve) => {
			setTimeout(() => {
				resolve(true)
			}, times)
		});
	}

	/**
	 * data 必须是一个对象  
	 */
	static sendMsg = (data) => {
		// 说明  已经链接了 
		// console.log(wss.ws,124)
		if (wss.ws || wss.ws.readyState != 0) {
			var flag
			try {
				// constructor 他检测 null 和 undefined 会报错
				// typeof 检测null  array function 都是 obejct
				// instanceof 判断数组时 也是ture [] instanceof Object ===true
				flag = (data).constructor === Object
			} catch (e) {
				flag = false
			}
			try {
				if (flag) {
					wss.ws.send(JSON.stringify(data))
				} else {
					wss.ws.send(JSON.stringify(data))
				}
			} catch (e) {
				//TODO handle the exception
				console.log("还没链接呢", data, 142)
				wss.XiaoXiList.push(data)
				// 对离线消息进行去重复 操作  
				wss.XiaoXiList = [...new Set(wss.XiaoXiList.map(JSON.stringify))].map(JSON.parse);
			}
			// console.log(flag, 32)
		} else {
			// 还没链接呢 
			console.log("还没链接呢")
		}
	}
}

export default wss